﻿using System.Collections.Generic;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;

namespace SHomeWorkshop.LunarPresentation.Adorners
{
    /// <summary>
    /// 上下标式的辅助线装饰器。
    /// </summary>
    public class AssistAdorner : Adorner
    {
        /// <summary>
        /// 上下标式的辅助线装饰器。
        /// </summary>
        public AssistAdorner(Expressions.MarkText adornedElement)
            : base(adornedElement)
        {
            //终于解决了选取装饰器中线条宽度为2而不是1像素的问题！！！
            this.SnapsToDevicePixels = true;
            this.SetValue(RenderOptions.EdgeModeProperty, EdgeMode.Aliased);

            this.masterMt = adornedElement;
            this.Cursor = Cursors.Hand;

            this.MouseLeftButtonDown += new MouseButtonEventHandler(AssistAdorner_MouseLeftButtonDown);
            this.MouseLeftButtonUp += new MouseButtonEventHandler(AssistAdorner_MouseLeftButtonUp);

            this.MouseRightButtonDown += new MouseButtonEventHandler(AssistAdorner_MouseRightButtonDown);
        }

        void AssistAdorner_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (masterMt != null && masterMt.Editor != null)
            {
                if (masterMt.Editor.SelectedExpression != masterMt)
                {
                    masterMt.Editor.SelectedExpression = masterMt;
                }
            }

            e.Handled = true;
        }

        void AssistAdorner_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            //完成拖动。
            Globals.DropExpression(this.masterMt);
        }

        void AssistAdorner_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (masterMt != null && masterMt.Editor != null)
            {
                if (masterMt.Editor.SelectedExpression != masterMt)
                {
                    masterMt.Editor.SelectedExpression = masterMt;
                }

                if (Globals.dragSourceExpression != masterMt)
                {
                    Globals.dragSourceExpression = masterMt;
                }
            }
            e.Handled = true;
        }

        private Expressions.MarkText masterMt;

        /// <summary>
        /// 使用本折叠标记的文本块。
        /// </summary>
        public Expressions.MarkText MasterMt
        {
            get { return masterMt; }
            set { masterMt = value; }
        }

        protected override void OnRender(DrawingContext drawingContext)
        {
            if (MasterMt == null) return;

            Rect rect = new Rect(this.AdornedElement.RenderSize);

            Brush renderBrush = masterMt.ExForeground;
            Pen renderPen = new Pen(renderBrush, 1) { EndLineCap = PenLineCap.Square };

            switch (masterMt.Midline)
            {
                case Expressions.MarkText.AssistLine.None: return;
                case Expressions.MarkText.AssistLine.RightArrow:
                    {
                        Point ptStart = new Point(rect.Left, rect.Top + rect.Height / 2);
                        Point ptEnd = new Point(rect.Right, ptStart.Y);

                        drawingContext.DrawLine(renderPen, ptStart, ptEnd);

                        Point pta = new Point(ptEnd.X - 4, ptEnd.Y - 4);
                        Point ptb = new Point(ptEnd.X - 4, ptEnd.Y + 4);

                        PathGeometry pathGeometry = new PathGeometry();
                        PathFigure pf = new PathFigure() { StartPoint = pta };
                        PolyLineSegment pls = new PolyLineSegment(
                            new List<Point>() { ptEnd, ptb, pta, ptEnd }, true);
                        pf.Segments.Add(pls);
                        pathGeometry.Figures.Add(pf);

                        drawingContext.DrawGeometry(renderBrush, renderPen, pathGeometry);

                        break;
                    }
                case Expressions.MarkText.AssistLine.LeftArrow:
                    {
                        Point ptStart = new Point(rect.Left, rect.Top + rect.Height / 2);
                        Point ptEnd = new Point(rect.Right, ptStart.Y);

                        drawingContext.DrawLine(renderPen, ptStart, ptEnd);

                        Point pta = new Point(ptStart.X + 5, ptStart.Y - 5);
                        Point ptb = new Point(ptStart.X + 5, ptStart.Y + 5);

                        PathGeometry pathGeometry = new PathGeometry();
                        PathFigure pf = new PathFigure() { StartPoint = pta };
                        PolyLineSegment pls = new PolyLineSegment(
                            new List<Point>() { ptStart, ptb, pta, ptStart }, true);
                        pf.Segments.Add(pls);
                        pathGeometry.Figures.Add(pf);

                        drawingContext.DrawGeometry(renderBrush, renderPen, pathGeometry);
                        break;
                    }
                case Expressions.MarkText.AssistLine.SingleLine:
                    {
                        Point ptStart = new Point(rect.Left, rect.Top + rect.Height / 2);
                        Point ptEnd = new Point(rect.Right, ptStart.Y);

                        drawingContext.DrawLine(renderPen, ptStart, ptEnd);
                        break;
                    }
                case Expressions.MarkText.AssistLine.DoubleLine:
                    {
                        Point ptStart = new Point(rect.Left, rect.Top + rect.Height / 2);
                        Point ptEnd = new Point(rect.Right, ptStart.Y);

                        drawingContext.DrawLine(renderPen,
                            new Point(ptStart.X, ptStart.Y - 1),
                            new Point(ptEnd.X, ptEnd.Y - 1));

                        drawingContext.DrawLine(renderPen,
                            new Point(ptStart.X, ptStart.Y + 1),
                            new Point(ptEnd.X, ptEnd.Y + 1));

                        break;
                    }
                case Expressions.MarkText.AssistLine.DoubleArrow:
                    {
                        Point ptStart = new Point(rect.Left, rect.Top + rect.Height / 2);
                        Point ptEnd = new Point(rect.Right, ptStart.Y);

                        Point ptS1 = new Point(ptStart.X, ptStart.Y - 1);
                        Point ptE1 = new Point(ptEnd.X, ptEnd.Y - 1);

                        drawingContext.DrawLine(renderPen, ptS1, ptE1);

                        Point ptS2 = new Point(ptStart.X, ptStart.Y + 1);
                        Point ptE2 = new Point(ptEnd.X, ptEnd.Y + 1);

                        drawingContext.DrawLine(renderPen, ptS2, ptE2);

                        drawingContext.DrawLine(renderPen,
                            new Point(ptE1.X - 4, ptE1.Y - 4), ptE1);

                        drawingContext.DrawLine(renderPen,
                            new Point(ptS2.X + 4, ptS2.Y + 4), ptS2);

                        break;
                    }
            }
        }
    }
}